<?php
// +----------------------------------------------------------------------
// | 杭州十禾信息科技有限公司
// +----------------------------------------------------------------------
// | Copyright (c) 2013-2015 http://www.shelpe.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: LeePuman <ysyzlsm@163.com>
// +----------------------------------------------------------------------

/**
 * 卡位模块（抢排名）
 * Author: Boya
 */
require_once APP_PATH . 'Lib/Library/GetRank.class.php';

class Ranking  
{
	// /**
	//  * 更新策略
	//  * @param  array $tactics_data   策略内容
	//  * @param  array $want_rank_data 排名内容
	//  * @return true | Exception                 
	//  */
	// function updateTactics($tactics_data,$want_rank_data){
	// 	try{
	// 		//实例化数据映射器
	// 		$tactics = M('tactics');
	// 		$want_rank = M('want_rank');

	// 		$tactics_res = $this->auth($tactics_data['user_id'],$tactics_data['tactics_id']);  //权限判断
	// 		if (!$tactics_res) {
	// 			throw new Exception('无权编辑',2);
	// 		}

	// 		//开启事务
	// 		//(注意:mysql不支持多层事务,这里采用laravel的做法,只在最外层开启事务)
	// 		$tactics->startTrans();

	// 		//tactics表
	// 		if($tactics->save($tactics_data) === false){
	// 			//更新失败
	// 			throw new Exception('tactics更新失败'.$tactics->getLastSql(),1);
	// 		}

	// 		//wank_rank表
	// 		$where['tactics_id'] = $tactics_data['tactics_id'];
	// 		foreach ($want_rank_data['want_rank'] as $keyword_id => $want_rank_value) {						
	// 			$this->check_want_rank_data($keyword_id,$want_rank_value);  //检查格式
	// 			$where['keyword_id'] = $keyword_id;
	// 			$want_rank_data['want_rank'] = $want_rank_value;
	// 			if ($want_rank->where($where)->save($want_rank_data)===false) {
	// 				//添加失败,抛出错误
	// 				throw new Exception("want_rank更新失败!".$want_rank->getLastSql(),1);
	// 			}	
	// 		}
	// 		return true;
	// 	}catch(Exception $e){
	// 		if ($tactics) {
 //        		$tactics->rollback();
 //        	}
 //        	throw $e;
	// 	}
	// }
	

	// /**
	//  * 通过策略id显示策略信息
	//  * @param  int $user_id    用户id
	//  * @param  int|array $tactics_id 策略id
	//  * @return array           策略信息
	//  */
 //    public function getRankingBytacticsId($user_id,$tactics_id,Paging $paging)
	// {
	// 	// if (is_array($tactics_id)) {
	// 	// 	foreach ($tactics_id as $key) {
	// 	// 		$this->check_tactics_id($key);
	// 	// 	}
	// 	// 	$tactics_id_qureStr = implode(',',$tactics_id);
	// 	// 	$where = "tactics.tactics_id IN ($tactics_id_qureStr)";
	// 	// }else{
	// 	// 	$this->check_tactics_id($tactics_id);
	// 	// 	$where = "tactics.tactics_id = $tactics_id";
	// 	// }
	// 	// $this->getRanking($user_id,$where,$paging);
	// }

	// /**
	//  * 根据用户id,得该用户的所有策略
	//  * @param  [int] $user_id [用户id]
	//  * @param  [bool] $executable [是不是可执行的,策略是开启状态]
	//  * @param  [bool] $rankable [是否获取实时排名]
	//  * @return [type]          [description]
	//  */
	// function getAllRanking($user_id,$executable = false,$rankable = true)
	// {
	// 	$this->check_user_id($user_id);
	// 	if ($executable) {
	// 		$where = "tactics.tactics_id != '' AND tactics.tactics_status = 1  AND tactics.user_id = $user_id";
	// 	}else{
	// 		$where = "tactics.tactics_id != '' AND tactics.user_id = $user_id";
	// 	}
	// 	return $this->getRanking($user_id,$where,null,$rankable);
	// }

	// /**
	//  * getRankingBytacticsId,getAllRanking 通用部分
	//  * @param  int $user_id 用户id
	//  * @param  mix $where   tactics.tactics_id 条件
	//  * @param  mix $paging   分页
	//  * @param  mix $rankable   是否获取实时排名
	//  * @return array          策略信息
	//  */
	// private function getRanking($user_id,$where,Paging $paging = null,$rankable = true)
	// {
	// 	$this->check_user_id($user_id);
	// 	$keywords = M('keywords'.$user_id);
	// 	$tableName = $keywords->getTableName();
	// 	$field = "tactics.tactics_id,
	// 	          tactics.tactics_modified_time,
	// 	          tactics.campaign_period,
	// 	          tactics.premium,
	// 	          tactics.heighest_price,
	// 			  adgroups.num_iid,
	// 			  `$tableName`.keyword_id,
	// 			  `$tableName`.campaign_id,
	// 			  `$tableName`.adgroup_id,
	// 			  `$tableName`.word,
	// 			  `$tableName`.max_price,
	// 			  `$tableName`.matchscope,
	// 			  want_rank.want_rank,
	// 			  want_rank.msg,
	// 			  want_rank.update_time_keyword,
	// 			  want_rank.doing";
	// 	if ($paging) {
	// 			$paging->setRowCount($keywords->join("RIGHT JOIN adgroups ON `$tableName`.adgroup_id = adgroups.adgroup_id")
	// 	                         ->join("LEFT JOIN want_rank ON `$tableName`.keyword_id = want_rank.keyword_id")
	//                              ->join("LEFT JOIN tactics ON tactics.tactics_id = want_rank.tactics_id")
	//                              ->where($where)->count());

	// 			$paging->setPageCount(ceil($paging->getRowCount()/$paging->getPageSize()));

	// 			$ranking_info = $keywords->field($field)->join("RIGHT JOIN adgroups ON `$tableName`.adgroup_id = adgroups.adgroup_id")
	// 							                         ->join("LEFT JOIN want_rank ON `$tableName`.keyword_id = want_rank.keyword_id")
	// 						                             ->join("LEFT JOIN tactics ON tactics.tactics_id = want_rank.tactics_id")
	// 						                             ->where($where)->limit($paging->getOffset().','.$paging->getPageSize())->select();
	// 	}else{
	// 			$ranking_info = $keywords->field($field)->join("RIGHT JOIN adgroups ON `$tableName`.adgroup_id = adgroups.adgroup_id")
	// 								                         ->join("LEFT JOIN want_rank ON `$tableName`.keyword_id = want_rank.keyword_id")
	// 							                             ->join("LEFT JOIN tactics ON tactics.tactics_id = want_rank.tactics_id")
	// 							                             ->where($where)->select();
	// 	}
	      
	//     // dump($keywords->getLastSql());
	    
	//     if ($rankable) {
	//     	//获取实时排名
	//     	$ranking_info = $this->getCurrentRank($ranking_info);
	//     }
		
	// 	if ($paging) {
	// 		$paging->setRes_array($ranking_info);
	// 	}else{
	// 		return $ranking_info;
	// 	}
	// }
	
	/**
	 * 得关键词以前的报表
	 * @param  array $keyword_ids  关键词数组
	 * @param  string $date_start  开始日期
	 * @param  string $date_end    结束日期
	 * @return array  $res         关键词报表
	 */
	function getWordOldReport($keyword_ids,$date_start,$date_end)
	{
		$queryStr = implode(',',$keyword_ids);
		$me = session('me');
		$this->check_user_id($me["user_id"]);
		$rpt_keyword = M('rpt_keyword'.$me["user_id"]);
		$tableName = $rpt_keyword->getTableName();
		$res = $rpt_keyword->query(
			"SELECT
				keyword_id,
			    sum(impressions) AS impression,
			    sum(click) AS click,
			    sum(cost) AS cost,
			    sum(
			        fav_item_count + fav_shop_count
			    ) AS favtotal,
			    sum(cart_total) AS carttotal,
			    sum(direct_pay + indirect_pay) AS transactiontotal,
			    sum(
			        direct_pay_count + indirect_pay_count
			    ) AS transactionshippingtotal,
			    sum(click) / sum(impressions) * 100 AS ctr,
			    sum(cost) / sum(click) / 100 AS cpc,
			    sum(direct_pay + indirect_pay) / sum(cost) AS roi
			FROM
			    `$tableName`
			WHERE
			    keyword_id IN ($queryStr)
			AND 
				(date BETWEEN '$date_start' AND '$date_end')
			GROUP BY
			    keyword_id"
		);

		$res_filter = '';
		foreach ($res as $key => &$value) {
			$temp = $value['keyword_id'];
			unset($value['keyword_id']);
			$value['cost'] = $value['cost'] ? $value['cost']/100 : $value['cost'];
			$value['ctr'] = $this->_numFormat($value['ctr']);
			$value['cpc'] = $this->_numFormat($value['cpc']);
			$value['roi'] = $this->_numFormat($value['roi']);
			$res_filter[$temp] = $value;
		}

		return $res_filter;
	}

	//输出精确到小数点后两位的浮点数
	function _numFormat($num)
	{
		if (!is_int($num)) {
			return round($num,2);
		}else{
			return $num;
		}
	}

    /**
     * 竞拍
     * @param  [int]  $userId         [用户id]
     * @param  [array] $campaign_infos[竞拍信息]
     * campaign_infos['关键词id'=>'出价']
     * @return [bool]                 [description]
     */
    function campaign($userId,$campaign_infos)
    {
    	//分析$campaign_infos
    	$keyword_ids = '';
    	foreach ($campaign_infos as $key => $msg) {
    		if(!preg_match('/^\d+$/',$key)){
				throw new Exception("关键词id格式错误! keyword_id: $key",3);
			}
			$keyword_ids[] = $key;
    	}

		//查询竞拍必须的信息
		$keywords = M('keywords'.$userId);
		$field = "keyword_id,
				  adgroup_id,
				  word,
				  max_price,
				  matchscope,mobile_is_default_price,max_mobile_price";
		$queryStr = implode(',',$keyword_ids);
		$where = "keyword_id IN ($queryStr)";
		$ranking_infos = $keywords->field($field)->where($where)->select();
		// dump($keywords->getLastSql());
		// die();

		//竞拍
		$campaign = '';
		foreach ($ranking_infos as $key => $ranking_info) {
			$campaign[$ranking_info['keyword_id']] = array(
				'keyword_id' => $ranking_info['keyword_id'],  //关键词id
				'adgroup_id' => $ranking_info['adgroup_id'],  //推广组id
				'word' => $ranking_info['word'],  //关键词
				'price' => $ranking_info['max_price'],  //当前价格
				'new_price' => $campaign_infos[$ranking_info['keyword_id']], //新价格,
				'new_matchscope' => $ranking_info['matchscope'],  //'关键词匹配方式',
				'default_mobile_price' => 1,  //'关键词匹配方式',
				'action' => 'adjust'  //标志位
			);
		}

		//执行竞拍
		return $res = R('Keyword/keywordsUpdate', array($campaign), 'Event');
    }	

	/**
	 * 查询原始价格
	 * @param  [array] $keyword_ids [关键词id]
	 * @return [array]              [原始价格]
	 */
	function getOriginalValue($tactics_id,$keyword_ids)
	{
		//检查格式并组织查询语句
		$temp = '';
		$qureStr = '';
		if(!preg_match('/^\d+$/',$tactics_id)){
			throw new Exception("卡位策略id格式错误! tactics_id: $tactics_id",3);
		}
		foreach (array_unique($keyword_ids) as $key => $msg) {
			if(!preg_match('/^\d+$/',trim($msg))){
				throw new Exception("关键词id格式错误! keyword_ids: printf($tactics_id,true)",3);
			}
			$temp[] = $msg;
		}
		$qureStr = implode(',',$temp);
		$where = "tactics_id = $tactics_id AND keyword_id IN ($qureStr)";

		//查询
		$want_rank = M('want_rank');
		$res = $want_rank->field('original_value')->where($where)->select();

		//没有设置原始价格
		foreach ($res as $key => $msg) {
			// dump($msg);
			// die();
			if (!$msg['original_value']) {
				throw new Exception("$keyword_ids[$key]", 4);
			}
		}
		// dump($want_rank->getLastSql());
		// die();
		return $res;
		
	}

	/**
	 * 获取关键词当前出价
	 * @param  [int] $userId      [用户id]
	 * @param  [array] $keyword_ids [关键词id]
	 * @return [array]              [关键词当前出价]
	 */
	function getCurrentValue($userId,$keyword_ids)
	{
		$keyword_qureStr = implode(',',$keyword_ids);
		$where = "keyword_id IN ($keyword_qureStr)";
		$keywords = M('keywords'.$userId);
		return $keywords->field('max_price')->where($where)->select();
	}

	//得卡位策略信息
	function getRankInfo(GetRank $getRank)
	{
		return $getRank->execute();
	}

	/**
	 * 获取实时排名
	 * @param  [array] $ranking_info [策略信息]
	 * @return [array]               [策略信息]
	 */
	function getCurrentRank($ranking_info)
	{
		$keywordMdl = new KeywordModel();
		foreach ($ranking_info as $msg) {
			$msg['rank'] = $keywordMdl->getCurrRank($msg['word'], $msg['num_iid']);
			$temp[] = $msg;
		}
		return $temp;
	}

	/**
	 * 权限判断
	 * @param  int $user_id    用户id
	 * @param  int $tactics_id 策略id
	 * @return bool            无权访问返回false
	 */
	function auth($user_id,$tactics_id)
	{
		$this->check_user_id($user_id);
		$this->check_tactics_id($tactics_id);  //检查格式
		$tactics = M('tactics');
		$where['tactics_id'] = $tactics_id;
		$field = array(
			'tactics_id',
			'user_id',
			'tactics_name',
			'tactics_status',
			'executions',
			'premium',
			'campaign_period',
			'heighest_price',
			'keyword_ids',
			'tactics_modified_time'
			);
		$res = $tactics->field($field)->where($where)->select();
		if ($res[0]['user_id'] != $user_id) {
			return false;
		}
		return $res[0];
	}

	/**
	 * 验证期望排名数据
	 * @param  int $keyword_id      关键词id
	 * @param  int $want_rank_value 期望的关键词排名
	 * @return Exception            格式不符合抛出错误8
	 */
	function check_want_rank_data($keyword_id,$want_rank_value)
	{
		if (!preg_match('/^[0-9]*$/',$keyword_id) || !preg_match('/^[1-9]\d{0,2}$/',$want_rank_value) || is_null($keyword_id) || is_null($want_rank_value)) {
			//$keyword_id 验证整数,$want_rank_value验证3位正整数
			//验证失败,抛出错误
			throw new Exception("关键词id或期望排名格式不符合要求",3);
		}
	}

	/**
	 * [检查溢价格式]
	 * @param  [type] $premium 溢价
	 * @return 格式正确返回1 ,不正确返回0
	 */
	static function check_premium($premium)
	{
		return (preg_match('/^([-+]?\d+)(\.\d+)?\%?$/',$premium));
	}

	/**
	 * 验证用户id
	 * @param  int $user_id 用户id
	 * @return Exception    格式不符合抛出错误3
	 */
	public function check_user_id($user_id)
	{	
		if (!preg_match('/^-?\d*$/',$user_id) || is_null($user_id)) {
			//可以是负整数和正整数
			throw new Exception('user_id格式不符合要求',3);
		}
	}

	/**
	 * 验证日期格式
	 * 例: 2016-01-21
	 * @param  string $date 日期
	 * @return Exception || $date
	 */
	public function check_date($date)
	{
		if (!preg_match('/^\d{4}-\d{1,2}-\d{1,2}$/',$date) || is_null($date)) {
			throw new Exception('日期格式不符合要求',3);
		}else{
			return $date;
		}
	}

	/**
	 * 验证策略id
	 * @param  int $tactics_id 策略id
	 * @return Exception       格式不符合抛出错误10
	 */
	public function check_tactics_id($tactics_id)
	{
		if (!preg_match('/^\d*$/',$tactics_id) || is_null($tactics_id)) {
			//验证正整数
			throw new Exception('tactics_id格式不符合要求',3);
		}
	}

	/**
	 * 多维数组转一维数组
	 * @param  array $arr 多维数组
	 * @return array      一维索引数组
	 */
	function changeTo_ODarray($arr)
	{
	    static $arr2;
	    foreach ($arr as $key => $val) {
	        if ( is_array ($val)) {
	            $this->changeTo_ODarray ($val);
	        } else {
	            $arr2[] = $val;
	        }
	    }
	    return $arr2;
	}

	function printError(Exception $e)
	{
		// file_put_contents (RUNTIME_PATH.'Logs/'.date("y_m_d").'_mlkr.log' , $e->getMessage().' '. date ( "Y-m-d H:i:s" ). " \r\n\r" , FILE_APPEND);
		$this->writeLog($e->getMessage());
		// dump($e->getMessage());
	}

	function writeLog($msg){
		if (is_array($msg)) {
			file_put_contents (RUNTIME_PATH.'Logs/'.date("y_m_d").'_mlkr.log' , print_r($msg,true).' '. date ( "Y-m-d H:i:s" ). " \r\n\r" , FILE_APPEND);
		}else if(is_string($msg)){
			file_put_contents (RUNTIME_PATH.'Logs/'.date("y_m_d").'_mlkr.log' , $msg.' '. date ( "Y-m-d H:i:s" ). " \r\n\r" , FILE_APPEND);
		}
	}

	/**
	 * 得错误描述
	 * @param  Exception $e [description]
	 * @return string       [description]
	 */
	function getErrorMessage(Exception $e)
	{
		$message = '';
    	switch ($e->getCode()) {
    		case 1:
    			$message = '数据库错误';
    			break;
    		case 2:
	    		$message = '权限错误';
	    		break;
    		case 3:
	    		$message = '格式错误';
	    		break;
	    	default:
				$message = '未知错误';
				break;
    	}
    	return $message;
	}
}